/*
 * Copyright (c) 2009 Robert Esser
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.e2ser;

import net.e2ser.component.Place;
import net.e2ser.component.Transition;
import net.e2ser.petri.Editor;
import net.e2ser.util.FileChooser;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

/**
 * The primary activity for the Petri Net Browser application
 * 
 * There are 2 alternative layouts for the UI for
 * portrait and landscape modes
 * 
 * @author Rob Esser
 * @version 12/8/2009
 *
 */
public class PNBrowser extends Activity {

  public static final String TAG = "PNBrowser";
  public static final String TEMP_FILE_NAME = "pnbrowser_tmp.xml";

  private static final int FC_OPEN = 3108;
  private static final int FC_SAVE = 0602;
  private static final String LASTFILENAME = "LASTFILENAME";
  
  //UI elements
  private Editor editor = null;
  private ImageButton stopButton = null;
  private ImageButton stepButton = null;
  private ImageButton forwardButton = null;
  private ImageButton fastForwardButton = null;
  private Button addTokenButton = null;
  private Button removeTokenButton = null;
  private ImageButton selectButton = null;
  private ImageButton connectButton = null;
  private ImageButton transitionButton = null;
  private ImageButton placeButton = null;
  private ImageButton deleteButton = null;
  private TextView statusView = null;
  
  //we save the last file name used to save or store a net
  private String lastfilename = "";

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    initializeViews();
    //Log.v(PNBrowser.TAG, "onCreate() called");
  }

  public void onPause() {
    // make sure the simulator is off
    editor.stop();
    //Log.v(PNBrowser.TAG, "onPause() called");
    super.onPause();
  }

  /** save some state between activations */
  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString(LASTFILENAME, lastfilename);
    editor.saveFile(PNBrowser.TEMP_FILE_NAME);
    super.onSaveInstanceState(savedInstanceState);
  }
  
  /** restore some state when returning from a near death experience */
  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    String fn = savedInstanceState.getString(LASTFILENAME);
    if (fn != null) {
      lastfilename = fn;
    }
  }

  /** set up all the UI related stuff */
  private void initializeViews() {
    editor = (Editor) findViewById(R.id.EditorView);
    // get control buttons
    stopButton = (ImageButton) findViewById(R.id.StopButton);
    stepButton = (ImageButton) findViewById(R.id.StepButton);
    forwardButton = (ImageButton) findViewById(R.id.ForwardButton);
    fastForwardButton = (ImageButton) findViewById(R.id.FastForwardButton);
    // get sundry buttons
    addTokenButton = (Button) findViewById(R.id.AddTokenButton);
    removeTokenButton = (Button) findViewById(R.id.RemoveTokenButton);
    // get edit buttons
    selectButton = (ImageButton) findViewById(R.id.SelectButton);
    connectButton = (ImageButton) findViewById(R.id.ConnectButton);
    placeButton = (ImageButton) findViewById(R.id.PlaceButton);
    transitionButton = (ImageButton) findViewById(R.id.TransitionButton);
    deleteButton = (ImageButton) findViewById(R.id.DeleteButton);
    //set up the status view
    statusView = (TextView) findViewById(R.id.StatusView);
    editor.setSatusView(statusView);
    
    enableAllControlButtonsExceptStop();
    selectButton.setEnabled(false);

    // set listeners
    stopButton.setOnClickListener(stopButtonListener);
    stepButton.setOnClickListener(stepButtonListener);
    forwardButton.setOnClickListener(forwardButtonListener);
    fastForwardButton.setOnClickListener(fastForwardButtonListener);
    
    addTokenButton.setOnClickListener(addTokenButtonListener);
    removeTokenButton.setOnClickListener(removeTokenButtonListener);
    
    selectButton.setOnClickListener(selectButtonListener);
    connectButton.setOnClickListener(connectButtonListener);
    placeButton.setOnClickListener(placeButtonListener);
    transitionButton.setOnClickListener(transitionButtonListener);
    deleteButton.setOnClickListener(deleteButtonListener);

    editor.showStatus("");
  }

  /** extract an options menu from the menu resource */
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    return true;
  }
  
  /** 
   * A call back from the FileChooser activity. Unlike standard Java dialogs are not modal
   * and hence some magic is needed
   */
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    Bundle extras = intent.getExtras();
    switch (requestCode) {
    case FC_OPEN:
      String ofn  = extras.getString(FileChooser.FILENAME);
      String opendirname = extras.getString(FileChooser.DIRNAME);
      Log.v(PNBrowser.TAG, "open activity fc: " + (ofn == null ? "null" : ofn)+ ", dirname: " + (opendirname == null ? "null" : opendirname));
      if (ofn != null && ofn.length() > 0) {
        lastfilename = ofn;
        editor.loadFile(lastfilename);
      } else {
        lastfilename = "";
      }
      break;
    case FC_SAVE:
      String sfn = extras.getString(FileChooser.FILENAME);
      String savedirname = extras.getString(FileChooser.DIRNAME);
      Log.v(PNBrowser.TAG, "save activity fc: " + (sfn == null ? "null" : sfn)+ ", dirname: " + (savedirname == null ? "null" : savedirname));
      if (sfn != null && sfn.length() > 0) {
        lastfilename = sfn;
        editor.saveFile(lastfilename);
      } else {
        lastfilename = "";
      }
      break;
    }
  } 
  
  /** Handles options menu item selections */
  public boolean onOptionsItemSelected(MenuItem item) {
    Log.v(PNBrowser.TAG, "Menu: " + item.getItemId());
      switch (item.getItemId()) {
      case R.id.open_net:
        Intent oi = new Intent(this, FileChooser.class);
        oi.putExtra(FileChooser.MODE, new Integer(FileChooser.OPEN_FILE_CHOOSER));
        startActivityForResult(oi, FC_OPEN);
        return true;
      case R.id.save_net:
        Intent si = new Intent(this, FileChooser.class);
        si.putExtra(FileChooser.MODE, new Integer(FileChooser.SAVE__FILE_CHOOSER));
        si.putExtra(FileChooser.FILENAME, lastfilename);
        startActivityForResult(si, FC_SAVE);
        return true;
      case R.id.about:
        Toast.makeText(this, R.string.aboutText, Toast.LENGTH_LONG).show();
        return true;
      }
      return false;
  }
 
  /**
   * listener for the stop button.
   */
  private OnClickListener stopButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.stop();
        enableAllControlButtonsExceptStop();
      }
    }
  };
  
  /**
   * listener for the step button.
   */
  private OnClickListener stepButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        disableAllControlButtonsExceptStop();
        editor.step();
        enableAllControlButtonsExceptStop();
      }
    }
  };

  /*
   * listener for the forward button.
   */
  private OnClickListener forwardButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.forward();
        disableAllControlButtonsExceptStop();
      }
    }
  };

  /*
   * listener for the fast forward button.
   */
  private OnClickListener fastForwardButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.fastForward();
        disableAllControlButtonsExceptStop();
      }
    }
  };

  /*
   * listener for the add token button.
   */
  private OnClickListener addTokenButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.insertTokens();
      }
    }
  };

  /*
   * listener for the remove token button.
   */
  private OnClickListener removeTokenButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.deleteTokens();
      }
    }
  };

  /*
   * listener for the select button.
   */
  private OnClickListener selectButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.toInsert(null);
        selectButton.setEnabled(false);
        connectButton.setEnabled(true);
        placeButton.setEnabled(true);
        transitionButton.setEnabled(true);
        deleteButton.setEnabled(true);
      }
    }
  };

  /*
   * listener for the connect button.
   */
  private OnClickListener connectButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.toInsertArc();
        selectButton.setEnabled(true);
        connectButton.setEnabled(true);
        placeButton.setEnabled(false);
        transitionButton.setEnabled(false);
        deleteButton.setEnabled(false);
      }
    }
  };

  /*
   * listener for the place button.
   */
  private OnClickListener placeButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.toInsert(new Place(null, Editor.DisplayScale));
        selectButton.setEnabled(true);
        connectButton.setEnabled(false);
        placeButton.setEnabled(true);
        transitionButton.setEnabled(false);
        deleteButton.setEnabled(false);
      }
    }
  };

  /*
   * listener for the transition button.
   */
  private OnClickListener transitionButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.toInsert(new Transition(null, Editor.DisplayScale));
        selectButton.setEnabled(true);
        connectButton.setEnabled(false);
        placeButton.setEnabled(false);
        transitionButton.setEnabled(true);
        deleteButton.setEnabled(false);
      }
    }
  };

  /*
   * listener for the delete button.
   */
  private OnClickListener deleteButtonListener = new OnClickListener() {
    public void onClick(View v) {
      if (v.isEnabled() && editor != null) {
        editor.delete();
        selectButton.setEnabled(true);
        connectButton.setEnabled(false);
        placeButton.setEnabled(false);
        transitionButton.setEnabled(false);
        deleteButton.setEnabled(true);
      }
    }
  };

  /** button mode control */
  private void enableAllControlButtonsExceptStop() {
    stopButton.setEnabled(false);
    stepButton.setEnabled(true);
    forwardButton.setEnabled(true);
    fastForwardButton.setEnabled(true);
  }

  /** button mode control */
  private void disableAllControlButtonsExceptStop() {
    stopButton.setEnabled(true);
    stepButton.setEnabled(false);
    forwardButton.setEnabled(false);
    fastForwardButton.setEnabled(false);
  }

}